local Util = require("common.Util")
local RoleAttr = require("role.RoleAttr")
local CombatDefine = require("combat.CombatDefine")
local CombatObj = require("combat.CombatObj")
local CombatImpl = require("combat.CombatImpl")
local TargetMode = require("combat.TargetMode")
local CombatCalc = require("combat.CombatCalc")
local RoleDefine = require("role.RoleDefine")
local BeSkill = require("combat.BeSkill")
local BufferExcel = require("excel.buffer")
local Skill = require("combat.Skill")
local SkillExcel = require("excel.skill").skill
local HeroExcel = require("excel.hero").hero
local FuwenExcel = require("excel.fuwen")
local ProjectLogic = require("platform.ProjectLogic")

--和血量相关的作用
local function isHpCmd(cmd)
	if cmd == "hp" or cmd == "hurt" or cmd == "hurt1" or cmd == "liuxue" or cmd == "zhongdu" or cmd == "ranshao" or cmd == "ranshao1" or cmd == "huiheYinji" then
		return true
	end
	return false
end

--控制类buff
function isControlCmd(cmd)
	if  cmd == "xuanyun" or cmd == "shihua" or cmd == "bingdong" or cmd == "chanrao" then
		return true
	end
end

--跳过行动回合
function isStop(obj)
	if obj == nil then
		return
	end
	local bufferCmd = obj.bufferCmd
	local ret
	if bufferCmd["xuanyun"] or bufferCmd["shihua"] or bufferCmd["bingdong"] or bufferCmd["chanrao"] then
		ret = 1
	elseif bufferCmd["xuanyun"] then
		ret = 2
	end
	return ret
end

--使用主动技能
function isJingji(obj)
	if obj.bufferCmd["jinmo"] then
		return true
	end
end

--是否缠绕
function isChanRao(obj)
	for j = obj.buffer[0], 1, -1 do
		local buffer = obj.buffer[j]
		local conf = BufferExcel.buffer[buffer.id]
		local cmd = conf.cmd
		if cmd == "chanrao" then
			return true
		end
	end
end

--是否被嘲讽
function isChaofen(obj)
	if obj and obj.buffer then
		for j = obj.buffer[0], 1, -1 do
			local buffer = obj.buffer[j]
			local conf = BufferExcel.buffer[buffer.id]
			local cmd = conf.cmd
			if cmd == "chaofeng" then
				local attackPos = buffer.attackPos
				local attacker = CombatImpl.objList[attackPos]
				if attacker and attacker.pos ~= obj.pos then
					return true,attackPos
				end
			end
		end
	end
	
	return false,0
end

--是否被控制
function isAtControl(obj)
	if obj and obj.buffer then
		for j = obj.buffer[0], 1, -1 do
			local buffer = obj.buffer[j]
			local conf = BufferExcel.buffer[buffer.id]
			local cmd = conf.cmd
			if isControlCmd(cmd) then
			   return true
			end
		end
	end
end

-- 检查能否复活
function canRevive(obj)
	if obj then
		if obj.hp > 0 then
			return
		end
		if obj.beBackup then
			return
		end
		if obj.dieSkill then
			local skillConf = SkillExcel[obj.dieSkill]
			if skillConf.otherArgs.noRevive == 1 then
				return false
			end
		end
		if obj.bufferCmd and obj.bufferCmd["noRevive"] then
			return false
		end

		for k,v in ipairs(CombatImpl.frameReviceList) do
			if v[1] == obj.pos then
				return false
			end
		end

		return true
	end	
end

--是否对某种状态免疫
CMD2KEY = {
	["xuanyun"] = RoleDefine.STATUS_MIANYI_RATE1,
	["shihua"] = RoleDefine.STATUS_MIANYI_RATE2,
	["bingdong"] = RoleDefine.STATUS_MIANYI_RATE3,
	["jinmo"] = RoleDefine.STATUS_MIANYI_RATE4,
	["ranshao"] = RoleDefine.STATUS_MIANYI_RATE5,
	["ranshao1"] = RoleDefine.STATUS_MIANYI_RATE5,
	["liuxue"] = RoleDefine.STATUS_MIANYI_RATE6,
	["zhongdu"] = RoleDefine.STATUS_MIANYI_RATE7,
    ["hunluan"] = RoleDefine.STATUS_MIANYI_RATE9,
}
function isMianyi(obj,cmd)
	local key = CMD2KEY[cmd]
	local r = math.random(0,10000)
	if key and obj.attr[key] >= r then
		return true
	end

    initCombatBufferType()
    -- 免疫所有负面状态
    if BUFFER_COMBAT_TYPE[cmd] and BUFFER_COMBAT_TYPE[cmd] == 1 then
       local r = math.random(0,10000)
       if obj.attr[RoleDefine.STATUS_MIANYI_RATE8] >= r then
		  return true
	   end
    end
end

local function isMiankong(obj, cmd, attacker, skillKongRate)
    if not isControlCmd(cmd) then return end
    if not attacker then return end
    if not skillKongRate then return end

    -- 新手剧情 100%控制
    if CombatImpl.fightMode[1] == CombatDefine.FIGHT_MODE2 then
       return false
    end

	local kongRate = attacker.attr[RoleDefine.KONG_RATE]
    -- 附带技能控制率
    kongRate = kongRate + skillKongRate

    local mianKongRate = obj.attr[RoleDefine.MIANKONG_RATE]
    kongRate = kongRate * (1 - mianKongRate/10000)
    kongRate = kongRate < 0 and 0 or kongRate
    -- 连击模式 控制概率
    if CombatImpl.comboType > 0 then
       kongRate = kongRate * CombatImpl.comboHurtRate / 10000
    end

	local r = math.random(1,10000)
	if r >= kongRate then
		return true
	end
end

function getStatus(obj)
	return obj.bufferCmd or {}
end

function isStatus(obj,status)
	local bufferCmd = obj.bufferCmd
	if not bufferCmd then return end
	for j = 1,#status do
		if bufferCmd[status[j]] then
			return true,status[j],bufferCmd[status[j]][1]
		end
	end
end

function isJob(obj,jobs)
	local job = obj.job
	for i = 1,#jobs do
		if job == jobs[i] then
			return true
		end
	end
end

function isCamp(obj,camps)
	local camp = obj.camp
	for i = 1,#camps do
		if camp == camps[i] then
			return true
		end
	end
end

function isSide(obj,sides, attacker)
    if not attacker then return end
	local side = obj.side
    -- 只能对敌方
    if sides == 1 then
        if side == attacker.side then
           return true
        end
    -- 只能对友方
    elseif sides == 2 then
        if side ~= attacker.side then
           return true
        end
    end
end

local function isPos(obj,posList)
	local pos = obj.pos
	for i = 1,#posList do
		if pos == posList[i] then
			return true
		end
	end
end


function getBuffer(obj)
	return obj.buffer
end

function onBufferChange(obj)
	local bufferAttr = obj.bufferAttr
	RoleAttr.initCombatAttr(bufferAttr)
	local bufferCmd = obj.bufferCmd
	for k,v in pairs(bufferCmd) do
		bufferCmd[k] = nil
	end

	local changeList = {}
	for i = 1, obj.buffer[0] do
		local buffer = obj.buffer[i]
		local conf = BufferExcel.buffer[buffer.id]

		if conf.cmd == "stealattr" or 
        conf.cmd == "handleattr" or 
        conf.cmd == "attr" or 
        conf.cmd == "attrdne" or
        conf.cmd == "attr1" or 
        conf.cmd == "pojia" or 
        conf.cmd == "jiansu" or 
        conf.cmd == "defRate" or 
        conf.cmd == "defRate2" or 
        conf.cmd == "attrQusan" then

			if type(buffer.arg) == "table" then
				for j = 1,#buffer.arg do
					local attrData = buffer.arg[j]
					local key = attrData[1]
                    local value = 0
                    if not conf.attrRate then
                       value = attrData[2] 
                    else
                       value = conf.attrRate
                    end
                    	
					RoleAttr.updateValue(key,value,bufferAttr,true)
				end
			else
				for j = 1,#conf.args do
					local attrData = conf.args[j]
					local key = attrData[1]
					local value = 0
                    if not conf.attrRate then
                       value = attrData[2] 
                    else
                       value = conf.attrRate
                    end

					RoleAttr.updateValue(key,buffer.arg or (value * buffer.cnt),bufferAttr,true)
				end
			end
		end
		
		if conf.cmd == "xuruo" then
			RoleAttr.updateValue(RoleDefine.XURUO,buffer.arg or conf.args[1],bufferAttr,true)
		end
		
		if conf.cmd == "fansheZhuangjia" then
			RoleAttr.updateValue(RoleDefine.FANSHE_ZHUANGJIA,conf.args[1],bufferAttr,true)
		end

		if conf.cmd == "hudun" then
			RoleAttr.updateValue(RoleDefine.HUDUN_COMBAT, buffer.arg, bufferAttr,true)
		end
		--标识，给其他英雄加属性的buff
		if conf.cmd == "biaoshi" then
			local attacker = buffer.attackPos and CombatImpl.objList[buffer.attackPos]
			if attacker then
				if not changeList[attacker.pos] then
					changeList[attacker.pos] = 1
					attacker.bufferAttr2[obj.pos] = {}
					RoleAttr.initCombatAttr(attacker.bufferAttr2[obj.pos])
				end
				for j = 1,#conf.args do
					local attrData = conf.args[j]
					local key = attrData[1]
					local value = attrData[2]
					RoleAttr.updateValue(key,buffer.arg or (value * buffer.cnt),attacker.bufferAttr2[obj.pos],true)
				end	
			end
		end
		bufferCmd[conf.cmd] = bufferCmd[conf.cmd] or {}
		bufferCmd[conf.cmd][#bufferCmd[conf.cmd] + 1] = i
	end	
	CombatObj.calcAttr(obj)
	for pos in pairs(changeList) do
		CombatObj.calcAttr(CombatImpl.objList[pos])
	end
end

local function canAdd(obj, id, random, attacker, skillConfig)
	local conf = BufferExcel.buffer[id]
	if not conf then
		return
	end
    -- 非控制buff 走随机
    if not isControlCmd(conf.cmd) then
       -- 新手剧情 100%控制
       if CombatImpl.fightMode[1] == CombatDefine.FIGHT_MODE2 then
          random = 10000
       end
      
       if random and not Util.checkRandom(random) then
		  return
	   end
    end

	if obj.pos > CombatDefine.COMBAT_HERO_ALL_CNT then
		return
	end
	if obj.hp <= 0 then
		if conf.cmd == "revive" then
			return true
		else
            if conf.cmd == "noRevive" then
               return true
            end
		end
		return
	end

	if conf.cmd == "fixPos" then
		return true
	end

	if #conf.jobs > 0 and not isJob(obj,conf.jobs) then
		return
	end

	if conf.camp and #conf.camp > 0 and not isCamp(obj,conf.camp) then
		return
	end

    -- 只能给友方或者敌对方加
    if conf.side and conf.side > 0 and isSide(obj, conf.side, attacker) then
	   return
	end

	if #conf.status > 0 and not isStatus(obj,conf.status) then
		return
	end
	
	if #conf.pos > 0 and not isPos(obj,conf.pos) then
		return
	end
	
	if isMianyi(obj,conf.cmd) then
		return
	end
	
	if isMiankong(obj,conf.cmd, attacker, random) then
		return
	end

	--连击 BUFF率为 本来的一半
	if CombatImpl.comboType > 0 then
		local random = math.random(1, 10000)
		if random < 5000 then
			return
		end
	end
	return true
end
--根据cmd删除buff
local function delBufferByCmd(obj,cmd,cnt)
	local delCnt = 0
	for j = obj.buffer[0], 1, -1 do
		local buffer = obj.buffer[j]
		local conf = BufferExcel.buffer[buffer.id]
		local bufferCmd = conf.cmd
		if bufferCmd == cmd then
			local bufferCnt = delBuffer(obj, j)
			CombatImpl.addFrameBuffer(obj,buffer,CombatDefine.BUFFER_OP_DEL)
			delCnt = delCnt + 1
			if delCnt == cnt then
				return
			end
		end
	end
end
--删除所有buff
local function delAllBuff(obj)
	for i = 1, obj.buffer[0] do
		obj.buffer[i] = nil
	end
	obj.buffer[0] = 0
end
--判断是否抵消buff
local function cancelBuffer(obj,conf)
	local cancelCmd = conf.cancelCmd[1]
	local cnt = conf.cancelCmd[2]
	if not (cancelCmd and cnt) then
		return
	end
	local nowCnt = getBuffCnt(obj,cancelCmd)
	if cnt < 0 then --全删抵消buff
		if nowCnt > 0 then
			delBufferByCmd(obj,cancelCmd,cnt)
			return true
		end
	elseif cnt == 0 then--不删抵消buff
		if nowCnt > 0 then
			return true
		end
	elseif cnt > 0 then--删指定数量抵消buff
		if nowCnt >= cnt then
			delBufferByCmd(obj,cancelCmd,cnt)
			return true
		end
	end
end

DELAY_BUFF_OP = false
DELAY_LIST = nil

--不可以延迟加的buffcmd（加的时候可能会触发删除其他buff的cmd）
NO_DELAY_BUFFCMD = {
	["convert"] = 1
}

local function delayBegin()
	if DELAY_BUFF_OP then
		return
	end
	DELAY_BUFF_OP = true
	DELAY_LIST = {del = {},add = {}}
end

local function delayEnd()
	if not DELAY_BUFF_OP then
		return
	end
	table.sort(DELAY_LIST.del,function(a,b)
		return a[2] > b[2]
	end)
	DELAY_BUFF_OP = false
	local delRecord = {}
	for k,v in ipairs(DELAY_LIST.del) do
		delRecord[v[1]] =delRecord[v[1]] or {}
		if not delRecord[v[1]][v[2]] then
			delBuffer(v[1], v[2])
			delRecord[v[1]][v[2]] = 1
		end
	end
	for k,v in ipairs(DELAY_LIST.add) do
		addBuffer(v[1],v[2], v[3], v[4],v[5],v[6])
	end
	DELAY_LIST = {del = {},add = {}}
end

local function beforeAddBuffer(attackPos,obj, id, skillID,arg,parentConf)
	local conf = BufferExcel.buffer[id]
	local bufferCmd = conf.cmd
	if bufferCmd == "fixPos" then

	elseif cancelBuffer(obj,conf) then
		return true
	elseif bufferCmd == "shengling" then

	elseif conf.holdOnDie ~= 1 and obj.hp <= 0 then 
		return true
	elseif conf.roundOne == 1 then
		for j = obj.buffer[0], 1, -1 do
			local buffer = obj.buffer[j]
			if buffer.id == id and buffer.attackPos == attackPos and buffer.round == conf.round then
				return true
			end
		end	
	end

	
	if conf.type == CombatDefine.BUFFER_TYPE4 then
		if handler[bufferCmd] then
			local attacker = CombatImpl.objList[attackPos]
			handler[bufferCmd](attacker,obj,conf)
		end	
		return true
	end

	if bufferCmd == "convert" then
		local bufferList = {}
		for j = obj.buffer[0], 1, -1 do
			local buffer = obj.buffer[j]
			if buffer.id == id then
				bufferList[#bufferList + 1] = j
			end
		end
		local needCnt = conf.args[1]
		if #bufferList + 1 < needCnt then
			return
		end
		for _,v in ipairs(bufferList) do
			local buffer = obj.buffer[v]
			local bufferCnt = delBuffer(obj, v)
			CombatImpl.addFrameBuffer(obj,buffer,CombatDefine.BUFFER_OP_DEL)
		end

		addBuffer(attackPos,obj, conf.args[2], skillID,arg,parentConf)
		return true
	end
end

-- 添加到复活列表
local function checkRevive(attackPos,obj,bufferID,skillID)
    local conf = BufferExcel.buffer[bufferID]
	if conf.cmd ~= "revive" then
		return
	end

	if not canRevive(obj) then
		return true
	end

	CombatImpl.addRevice(attackPos, obj, bufferID, skillID)
	return true
end

-- 复活对象
function reviceObj(attackPos, obj, bufferID, skillID)
    local conf = BufferExcel.buffer[bufferID]
    if not conf then return end
    local skillConf = skillID and SkillExcel[skillID]
    if not skillConf then return end

    local attacker = CombatImpl.objList[attackPos]
    local hpRevive = CombatCalc.calcHp(attacker, obj, conf.args[1], conf.args[2], true)
    local hpAddRate = CombatObj.getValue(attacker,RoleDefine.ZAOCHENG_HP_ADD_RATE) / 10000
    hpRevive = hpRevive * (1 + hpAddRate)
	hpRevive = hpRevive < 0 and 1 or hpRevive

	local d = CombatObj.updateHp(obj, hpRevive, true, nil, nil, CombatObj.EXTRA_HP_TYPE)
	local attrs = {}
	attrs[RoleDefine.REVIVE_COMBAT] = attackPos
    
    CombatImpl.setSkillID(attacker, skillID)
    CombatImpl.setSkillHit(obj,0, nil, nil, attacker, skillID)
    CombatImpl.setSaySkill(attacker.pos,skillConf.id,skillConf.contentType)
	CombatImpl.setExtraHit(obj,d,Skill.getCMD2ID("revive"),attrs)
	if skillConf and skillConf.type == 0 then
		onExtraCombatRecord(attackPos, 1, "reviveBeUse")
	else
		onExtraCombatRecord(attackPos, 1, "revive")
	end

    if skillConf.cmd == "revive" then
       local buffers = skillConf.args
       local addBufferID = buffers[1]
       if addBufferID then
          local targetMode = buffers[2]
	      local random = buffers[3]
          local targets = TargetMode.getTargets(obj, targetMode)
          if #targets > 0 then
             for _,target in ipairs(targets) do
                if canAdd(target, addBufferID, random, obj, skillConf) then 
	      	        addBuffer(obj.pos, target, addBufferID, skillConf.id, arg)
	      	     end
             end
          end
       end
    end
	BeSkill.onAddBuffer(obj,{id = bufferID})
end


function addBuffer(attackPos,obj, id, skillID,arg,parentConf)
	local conf = BufferExcel.buffer[id]
	local bufferCmd = conf.cmd
	if DELAY_BUFF_OP then
		if not NO_DELAY_BUFFCMD[bufferCmd] then
			DELAY_LIST.add[#DELAY_LIST.add + 1] = {attackPos,obj, id, skillID,arg,parentConf}
		end

		return
	end
	
    if checkRevive(attackPos,obj, id, skillID) then
		return
	end

	if beforeAddBuffer(attackPos,obj, id, skillID,arg,parentConf) then
		return
	end

	local bufferCnt = 1
	local index
	local buffer
	local bufferCmdInd
	local bufferInd
    local tround = 0
	local index = 0
	local groupCnt = 0
	local group = conf.group[1]
	for i = 1, obj.buffer[0] do
		buffer = obj.buffer[i]
		if buffer.id == id then
			bufferCnt = bufferCnt + 1
			bufferInd = i
            if tround > buffer.round or tround == 0 then
				tround = buffer.round
				index = i
			end
		end
		local nowBuffConf = BufferExcel.buffer[buffer.id]
		if  nowBuffConf.cmd == bufferCmd then
			bufferCmdInd = i
		end
		if group and group == nowBuffConf.group[1] then
			groupCnt = groupCnt + 1
		end
	end
     
	local groupCmd = conf.group[2]
	if groupCmd and groupCnt > 0 and groupCnt >= groupCmd then
		return
	end

	if bufferCnt > 100 then
		return
	end
	
	local canAppend = parentConf and parentConf.canAppend or conf.canAppend
	local round = parentConf and parentConf.round or conf.round
	
	round = round == 0 and 1 or round 
	if canAppend == 1 then
		local appendCnt = conf.appendCnt or 0
		if appendCnt > 0 and bufferCnt > conf.appendCnt then
            if conf.type ==  CombatDefine.BUFFER_TYPE2 then 
				buffer = obj.buffer[index]
				buffer.round = round
                --bingdong清除buffer参数
                if conf.cmd == "bingdong" then
                   buffer.arg = nil 
                end
		        CombatImpl.onAddBuffer(id)
		        CombatImpl.addFrameBuffer(obj,buffer,CombatDefine.BUFFER_OP_ADD,0)
                return
			end
			return
		end
	else
		if bufferCnt > 1 then
			if conf.type ==  CombatDefine.BUFFER_TYPE2 then 
				buffer = obj.buffer[bufferInd]
				buffer.round = round
                --bingdong清除buffer参数
                if conf.cmd == "bingdong" then
                   buffer.arg = nil 
                end
		        CombatImpl.onAddBuffer(id)
		        CombatImpl.addFrameBuffer(obj,buffer,CombatDefine.BUFFER_OP_ADD,0)
                return
			end
			return
		end
	end

	if isControlCmd(bufferCmd) and bufferCmdInd then
		buffer = obj.buffer[bufferCmdInd]
		if buffer.round < round then
			buffer.round = round
		end
        if conf.cmd == "bingdong" then
           buffer.arg = nil 
        end
		return
	end
	
	obj.buffer[0] = obj.buffer[0] + 1
	index = obj.buffer[0]
	buffer = obj.buffer[index]
	if not buffer then
		obj.buffer[index] = {}
		buffer = obj.buffer[index]
	end

	buffer.id = id 
	buffer.round = nil 			-- 剩余回合
	buffer.attrs = nil
	buffer.attackPos = nil
	buffer.skillID = nil
	buffer.cnt = 1
	buffer.arg = nil
	
	if round then
		buffer.round = round
	elseif conf.type ==  CombatDefine.BUFFER_TYPE1 then
		buffer.round = 1
	elseif conf.type ==  CombatDefine.BUFFER_TYPE2 then 
		buffer.round = round
	elseif conf.type ==  CombatDefine.BUFFER_TYPE3 then 
		buffer.round = nil
	else
		assert()
	end

	local attacker
	if attackPos > CombatDefine.COMBAT_HERO_ALL_CNT then
		attacker = CombatImpl.helpList[attackPos]
	else
		attacker = CombatImpl.objList[attackPos]
	end
	if arg then
		buffer.arg = arg
	elseif isHpCmd(conf.cmd) then
		local isAddHp = conf.cmd == "hp"
		buffer.arg = CombatCalc.calcBufferHp(attacker,obj,id,isAddHp)
	end
	buffer.attackPos = attackPos
	buffer.skillID = skillID
	
	buffer.attrs = {}
	
	if  bufferCmd == "shengling" then
		buffer.arg = conf.args[3]
	elseif bufferCmd == "hudun" then
		local attackerHp = CombatCalc.calcHp(attacker, obj, conf.args[1], conf.args[2], true)
		local hudunValue = math.floor(conf.args[2] * attackerHp / 10000)
		buffer.arg = hudunValue
	end

	onBufferChange(obj)
	if conf.isAddCmd == 1 and handler[conf.cmd] then
		handler[conf.cmd](obj,buffer,conf)
		HANDLER_ONCE[conf.cmd] = nil
	end
	
	if conf.type ~= CombatDefine.BUFFER_TYPE1 then
		CombatImpl.onAddBuffer(id)
		CombatImpl.addFrameBuffer(obj,buffer,CombatDefine.BUFFER_OP_ADD)
	end
	BeSkill.onAddBuffer(obj,buffer)
	onExtraCombatRecord(attackPos,1,bufferCmd)
	return buffer
end

local function delBufferByTotem(obj,totemId)
	for j = obj.buffer[0], 1, -1 do
		local buffer = obj.buffer[j]
		local conf = BufferExcel.buffer[buffer.id]
		if bufferCmd ~= "totem" and buffer.totem == totemId then
			delBuffer(obj,j)
		end
	end
end

local function beforeDelBuffer(obj, buffer)
	local conf = BufferExcel.buffer[buffer.id]
	if conf.cmd == "fentan" and buffer.round < 1 then
	   local hurt = CombatCalc.calcHp(obj, obj, conf.args[1], conf.args[2])
       if hurt > 0 then
	      local d = CombatObj.updateHp(obj, hurt, nil, nil, buffer.attackPos,CombatObj.BUFFER_HP_TYPE)
	      CombatImpl.setExtraHit(obj, hurt)
          CombatObj.onHpCB(obj, d, obj.pos)
       end
    end
end

function delBuffer(obj, ind)
	if not obj.buffer[ind] then
		return
	end

	if DELAY_BUFF_OP then
		for k,v in ipairs(DELAY_LIST.del) do
			if v[2] == ind then
				return
			end
		end
		DELAY_LIST.del[#DELAY_LIST.del + 1] = {obj, ind}
		return
	end
	local id = obj.buffer[ind].id
	beforeDelBuffer(obj,obj.buffer[ind])
	obj.buffer[ind] = obj.buffer[obj.buffer[0]]
	obj.buffer[obj.buffer[0]] = nil
	obj.buffer[0] = obj.buffer[0] - 1
	onBufferChange(obj)
	local bufferCnt = 0
	for i = 1, obj.buffer[0] do
		local buffer = obj.buffer[i]
		if buffer.id ==	 id then
			bufferCnt = bufferCnt + 1
		end
	end	
	return bufferCnt
end

-- 战斗回合开始时添加buffer
function beforeCombat()

end

function getSkillBuffers(skillConfig)
	local randBuffCnt = skillConfig.otherArgs.randBuffCnt
	if not randBuffCnt then
		return skillConfig.buffers
	end
	local ret = {}
	local c = #skillConfig.buffers
	if randBuffCnt >= c then
		return skillConfig.buffers
	end
	for i = 1,c do
		ret[i] = skillConfig.buffers[i]
	end

	for i = 1,c do
		if i <= randBuffCnt then
			local r = math.random(i,c)
			ret[i],ret[r] = ret[r],ret[i]
		else
			ret[i] = nil
		end
	end
	return ret
end


-- 战斗回合中触发buffer
function onHit(attacker, skillTargets, skillConfig, cmdTargets, otherArgs)
    -- 处理施法者身上的buff
    if skillConfig.type == CombatDefine.SKILL_TYPE2 and
        attacker.buffer ~= nil then
        delayBegin()
        for j = attacker.buffer[0], 1, -1 do
            local buffer = attacker.buffer[j]
            local conf = BufferExcel.buffer[buffer.id]
            buffer.attrs = { }
            if attacker.hp > 0 and handlerEx[conf.cmd] then
                if handlerEx[conf.cmd](attacker, buffer, conf) then
                    CombatImpl.addFrameBuffer(attacker, buffer, CombatDefine.BUFFER_OP_HOLD)
                end
            end
        end
        delayEnd()
    end

    for k, v in ipairs(skillTargets) do
        if attacker.helpType == 0 and attacker.side ~= v.side then
            local fantanBufferInd = v.bufferCmd["fantan"] and v.bufferCmd["fantan"][1]
            local fantanBuffer = v.buffer[fantanBufferInd]
            if fantanBuffer then
                local conf = BufferExcel.buffer[fantanBuffer.id]

                -- 是否限制技能类型
                local bHit = false
                if conf.args[3] then
                    if conf.args[3] == skillConfig.type then
                        bHit = true
                    end
                else
                    bHit = true
                end

                if bHit then
                    local hurt = CombatCalc.calcHp(attacker, v, conf.args[1], conf.args[2])
                    local d = CombatObj.updateHp(attacker, - hurt, nil, nil, v.pos, CombatObj.BUFFER_HP_TYPE)
                    CombatImpl.setExtraHit(attacker, d)
                    CombatObj.onHpCB(attacker, d, v.pos)
                end
            end
        end

        -- 只能敌方攻击触发降低冰冻
        if not(otherArgs and otherArgs.noFirst) and skillConfig.hurtRate[1] then
            local bufferCmd = v.bufferCmd["bingdong"]
            if bufferCmd then
                local delList = { }
                for i = #bufferCmd, 1, -1 do
                    local bingdongBuffer = v.buffer[bufferCmd[i]]
                    local conf = BufferExcel.buffer[bingdongBuffer.id]
                    bingdongBuffer.arg = bingdongBuffer.arg or 0
                    bingdongBuffer.arg = bingdongBuffer.arg + 1
                    if bingdongBuffer.arg >=(conf.args[1] or 0) then
                        delList[#delList + 1] = bufferCmd[i]
                    end
                end
                --冰冻buffer被打碎
                if #delList > 0 then
                   local delBuffer = v.buffer[delList[1]]
                   BeSkill.onDelBingDongBuffer(v, delBuffer)
                end

                for k1, v1 in ipairs(delList) do
                    local buffer = v.buffer[v1]
                    local bufferCnt = delBuffer(v, v1)
                    CombatImpl.addFrameBuffer(v, buffer, CombatDefine.BUFFER_OP_DEL)
                end
            end
        end
    end

    local buffers = getSkillBuffers(skillConfig)
    local statusBuffRate = skillConfig.otherArgs.statusBuffRate
    for i = 1, #buffers do
        local bufferID = buffers[i][1]
        if type(bufferID) == "table" then
            local r = math.random(1, #bufferID)
            bufferID = bufferID[r]
        end

        local targetMode = buffers[i][2]
        local random = buffers[i][3]
        local bufferEx = buffers[i][4]
        local delayRound = buffers[i][5]
        if attacker.isPet and #skillConfig.bufferGrow > 0 then
            local growRate = 0
            local bufLv = attacker.lv
            if attacker.quality > 1 then
                bufLv = attacker.lv -(attacker.quality - 1) * 30
            end
            if skillConfig.bufferGrow and skillConfig.bufferGrow[i] then
                local gorwRat = skillConfig.bufferGrow[i][1]
                local growLv = skillConfig.bufferGrow[i][2]
                growRate = math.floor(bufLv / growLv) * gorwRat
            end
            random = random + growRate
        end

        local targets = TargetMode.getTargets(attacker, targetMode, skillTargets, cmdTargets, nil, nil, skillConfig.id)
        if #targets > 0 then
            local bufferConf = BufferExcel.buffer[bufferID]
            for _, target in ipairs(targets) do
                local r = random
                if statusBuffRate and bufferConf.cmd == statusBuffRate[1] and isStatus(target, statusBuffRate[2]) then
                    r = r + statusBuffRate[3]
                end
                if canAdd(target, bufferID, r, attacker, skillConfig) then
                    local arg
                    if bufferConf.cmd == "zuzhou" then
                        local rate = bufferConf.args[2] + BeSkill.getBufferExtraHurt(attacker, bufferID, bufferConf.cmd)
                        arg = { CombatCalc.calcHp(attacker, target, bufferConf.args[1], rate) }
                    end

                    if bufferConf.cmd == "stealattr" then
                        local value = CombatCalc.calcValue(attacker, target, bufferConf.args[1], bufferConf.args[2])
                        arg = { { bufferConf.args[3], value } }
                    end

                    if bufferConf.cmd == "handleattr" then
                        arg = { }
                        if attacker.handleAttr then
                            local value = attacker.handleAttr[2] *(bufferConf.args[1] / 10000)
                            if target.side == attacker.side then
                                arg = { { attacker.handleAttr[1], value * bufferConf.args[2] } }
                            else
                                arg = { { attacker.handleAttr[1], - value } }
                            end
                        end
                    end

                    if delayRound and delayRound > 0 then
                        target.delayAddBuffer = target.delayAddBuffer or { }
                        target.delayAddBuffer[#target.delayAddBuffer + 1] = { delayRound, attacker.pos, bufferID, skillConfig.id, arg }
                    else
                        addBuffer(attacker.pos, target, bufferID, skillConfig.id, arg)
                    end

                    
                    if bufferEx then
                        local bufferID = bufferEx[1]
                        local random = bufferEx[2]
                        local delayRound = bufferEx[3]
                        local bufferConf = BufferExcel.buffer[bufferID]
                        for _, target in ipairs(targets) do
                            local r = random
                            if canAdd(target, bufferID, r, attacker, skillConfig) then
                                local arg
                                if bufferConf.cmd == "zuzhou" then
                                    local rate = bufferConf.args[2] + BeSkill.getBufferExtraHurt(attacker, bufferID, bufferConf.cmd)
                                    arg = { CombatCalc.calcHp(attacker, target, bufferConf.args[1], rate) }
                                end

                                if bufferConf.cmd == "stealattr" then
                                    local value = CombatCalc.calcValue(attacker, target, bufferConf.args[1], bufferConf.args[2])
                                    arg = { { bufferConf.args[3], value } }
                                end

                                if bufferConf.cmd == "handleattr" then
                                    arg = { }
                                    if attacker.handleAttr then
                                        local value = attacker.handleAttr[2] *(bufferConf.args[1] / 10000)
                                        if target.side == attacker.side then
                                            arg = { { attacker.handleAttr[1], value * bufferConf.args[2] } }
                                        else
                                            arg = { { attacker.handleAttr[1], - value } }
                                        end
                                    end
                                end

                                if delayRound and delayRound > 0 then
                                    target.delayAddBuffer = target.delayAddBuffer or { }
                                    target.delayAddBuffer[#target.delayAddBuffer + 1] = { delayRound, attacker.pos, bufferID, skillConfig.id, arg }
                                else
                                    addBuffer(attacker.pos, target, bufferID, skillConfig.id, arg)
                                end
                            end
                        end
                    end
                end
            end
        end
    end
end

local function getBeskillBuffers(attacker,skillConfig)
	if skillConfig.otherArgs.buffer then 
		local checkArg = skillConfig.otherArgs.buffer
		local checkValue
		if checkArg.cmd == "hurtRate" then
			checkValue = -attacker.combatResult[1]
		elseif checkArg.cmd == "hpRate" then
			checkValue = attacker.combatResult[2]
		end
		if checkValue and checkValue > 0 then
			local hpMax = attacker.attr[RoleDefine.HP]
			local rate = (10000 * checkValue)/(hpMax * checkArg.param[1])
			if rate > 1 then
				local retArg = {}
				for k,v in ipairs(checkArg.param[2]) do
					retArg[#retArg + 1] = {v[1],math.floor(v[2] * rate)}
				end
				return skillConfig.buffers,retArg
			end
		end
	else
		return skillConfig.buffers
	end
end

function onUseBeSkill(attacker,skillConfig,objs,cmdTargets, arg)--attacker是被动技能释放者，objs是attacker的对立方（attacker是攻击者的话，objs是被攻击者，attacker是被攻击者的话，objs是攻击者）,cmdTargets是额外作用对象
	local buffers,bufferArg = getBeskillBuffers(attacker,skillConfig)
	if not buffers then
		return
	end
    bufferArg = bufferArg or arg

	local isAddSkillFrame
	local bufferArg1
	for i = 1, #buffers do
		local bufferID = buffers[i][1]
		local bufferConf = BufferExcel.buffer[bufferID]
		local targetMode = buffers[i][2]
		local targets
		bufferArg1 = nil
		if targetMode[1] == 13 then
			targets = objs
		else
			targets = TargetMode.getTargets(attacker, targetMode,objs,cmdTargets)
		end

		if #targets > 0 then
			if bufferConf.cmd == "zuzhou" then
				local rate = bufferConf.args[2] + BeSkill.getBufferExtraHurt(attacker,bufferID)
				bufferArg1 = {CombatCalc.calcHp(attacker,targets[1],bufferConf.args[1],rate)}
			end
			local attackPos = attacker.pos
			if bufferConf.roundOne == 1 and objs and objs[1] then
				attackPos = objs[1].pos
			end
			for _,target in ipairs(targets) do
				if canAdd(target,bufferID,buffers[i][3], attacker, skillConfig) then
					isAddSkillFrame = true
					addBuffer(attackPos,target, bufferID,skillConfig.id,bufferArg1 or bufferArg)
				end
			end
		end
	end
	return isAddSkillFrame
end

--战斗回合结束时处理buffer效果。删除失效buffer
--只执行一次的cmd，比如持续加血。
HANDLER_ONCE = HANDLER_ONCE or {}
function onRoundEnd(attacker,isRoundEnd)
	--处理施法者身上的buff	
	for i = 1,CombatDefine.COMBAT_HERO_ALL_CNT do
        local obj = CombatImpl.objList[i]
		if obj then
			for k,v in pairs(HANDLER_ONCE) do
				HANDLER_ONCE[k] = nil
			end
			delayBegin()
			for j = obj.buffer[0], 1, -1 do
				local buffer = obj.buffer[j]
				local conf = BufferExcel.buffer[buffer.id]
				if conf.type == CombatDefine.BUFFER_TYPE1 or isRoundEnd then
					buffer.attrs = {}
					local setFrame = false
					if conf.type ~= CombatDefine.BUFFER_TYPE4 and handler[conf.cmd] then
						if obj.hp > 0 or conf.cmd == "totem" then
                            if conf.cmd == "zuzhou" then
                                -- 最后一回合生效
                                if buffer.round == 1 then
                                   handler[conf.cmd](obj, buffer,conf)
                                   CombatImpl.addFrameBuffer(obj,buffer,CombatDefine.BUFFER_OP_HOLD)
                                end
                            else
							    handler[conf.cmd](obj, buffer,conf)
							    CombatImpl.addFrameBuffer(obj,buffer,CombatDefine.BUFFER_OP_HOLD)
                            end
						end
					end
					
					if buffer.round then
						local cmd = conf.cmd
						buffer.round = buffer.round - 1
						if buffer.round < 1 then
							local bufferCnt = delBuffer(obj, j)
							if (conf.type ~= CombatDefine.BUFFER_TYPE1 and obj.hp > 0) or conf.cmd == "fixPos" or conf.holdOnDie == 1 then
								CombatImpl.addFrameBuffer(obj,buffer,CombatDefine.BUFFER_OP_DEL)
							end
						end		
					end
				end
			end

			if isRoundEnd and obj.delayAddBuffer then
				--{delayRound,attacker.pos,bufferID,skillConfig.id,arg} 
				for k,v in ipairs(obj.delayAddBuffer) do
					v[1] = v[1] - 1
				end

				local temp = {}
				for i = 1,#obj.delayAddBuffer do
					local data = obj.delayAddBuffer[i]
					if data[1] > 0 then
						temp[#temp + 1] = data
					else
						addBuffer(data[2],obj,data[3],data[4],data[5])
					end 
				end
				if #temp > 0 then
					obj.delayAddBuffer = temp
				else
					obj.delayAddBuffer = nil
				end
			end
			delayEnd()
		end
	end
	for k,v in pairs(HANDLER_ONCE) do
		HANDLER_ONCE[k] = nil
	end
end
--攻击结束后，反击前，整合buffer前处理buffer效果
function beforeFanji()
	local isFanshe = false
	for i = 1,CombatDefine.COMBAT_HERO_ALL_CNT do
        local obj = CombatImpl.objList[i]
		if obj then
			for k,v in pairs(obj.combatResult[3]) do
				if k ~= i and v[1] and v[1] < 0 then
					local target = CombatImpl.objList[k]
					if target and target.hp > 0 then
						local d = CombatObj.updateHp(target, v[1], nil, nil, obj.pos,CombatObj.BUFFER_HP_TYPE)
						CombatImpl.setExtraHit(target,d)
						CombatObj.onHpCB(target,d, obj.pos)
						isFanshe = true
					end
				end
			end
			if isFanshe then
				delBufferByCmd(obj,"fansheZhuangjia",1)
			end
		end
	end
end

function getExtraHurtRate(attacker,target,skillConfig)
	local skillID = skillConfig.id
	local isBaoji = target.isBaoji
	local baojiHurtRate = 0
	local guanxinzheHurtRate = 0
	local huiheHurtRate = 0
	local shandianHurtRate = 0
	local attackerHurtRat = 0
	local biaoshiHurtRate = 0
	local biaoshiCnt = 0
	local biaoshiCntLimit
	if skillConfig.otherArgs.biaoshiHurtRate then
		biaoshiCntLimit = skillConfig.otherArgs.biaoshiHurtRate[1]
	end

	for j = target.buffer[0], 1, -1 do
		local obj = target
		local buffer = obj.buffer[j]
		local conf = BufferExcel.buffer[buffer.id]
		if conf.cmd == "guanxinzheYinji" then --观星者印记
			guanxinzheHurtRate = guanxinzheHurtRate + conf.args[2]
		elseif conf.cmd == "shandianYinji" then	--闪电印记
			for _,v in ipairs(conf.args[2]) do
				if skillID == v then
					shandianHurtRate = shandianHurtRate + conf.args[3]
					break	
				end
			end
		elseif conf.cmd == "biaoshi" then
			biaoshiCnt = biaoshiCnt + 1
		end
	end

	guanxinzheHurtRate = guanxinzheHurtRate > 30000 and 30000 or guanxinzheHurtRate --300%限制
	if biaoshiCntLimit and biaoshiCnt >= biaoshiCntLimit then
		biaoshiHurtRate = skillConfig.otherArgs.biaoshiHurtRate[2]
	end

	local extraHurtRate = baojiHurtRate + guanxinzheHurtRate + huiheHurtRate + shandianHurtRate + attackerHurtRat + biaoshiHurtRate
	return extraHurtRate
end

function getExtraHurt(attacker, target, skillConfig)
    local extraHurt = 0
    for j = target.buffer[0], 1, -1 do
		local obj = target
		local buffer = obj.buffer[j]
		local conf = BufferExcel.buffer[buffer.id]
		if conf.cmd == "shenhuo" then
            local hurt = CombatCalc.calcHp(attacker, target, conf.args[1], conf.args[2], true)
			extraHurt = extraHurt + hurt
		end
	end
	return extraHurt
end
	
--处理器
local function chixuHurtDel(target,buffer)
    local hurt = buffer.arg
	local hurtDelRate = target.attr[RoleDefine.CHIXU_HURT_DEL_RATE] / 10000
    --持续类buff 伤害加成
    local attacker = CombatImpl.objList[buffer.attackPos]
    local conf = BufferExcel.buffer[buffer.id]
    local beSkillHurtRate = BeSkill.getBuffChixuHurt(attacker, conf.cmd)
	hurtDelRate = hurtDelRate > 1 and 1 or hurtDelRate
	if hurtDelRate > 0 or beSkillHurtRate > 0 then
		hurt = hurt * (1 - hurtDelRate + beSkillHurtRate)
	end
	return hurt
end
handler = {}


--持续伤害
function handler.hurt(target, buffer,conf)
	local hurt = chixuHurtDel(target,buffer)
	local d = CombatObj.updateHp(target, -hurt, nil, nil, buffer.attackPos,CombatObj.BUFFER_HP_TYPE)
	buffer.attrs[RoleDefine.HP_COMBAT] = -hurt
end

--燃烧
function handler.hurt1(target, buffer,conf)
	local hurt = chixuHurtDel(target,buffer)
	local d = CombatObj.updateHp(target, -hurt, nil, nil, buffer.attackPos,CombatObj.BUFFER_HP_TYPE)
	buffer.attrs[RoleDefine.HP_COMBAT] = -hurt
    onExtraCombatRecord(buffer.attackPos,hurt,"ranshao")

    -- 删除attr1 buffer
    local attacker = CombatImpl.objList[buffer.attackPos]
	if attacker and attacker.bufferCmd["attr1"] then
		for i = #attacker.bufferCmd["attr1"],1,-1 do
            local ind = attacker.bufferCmd["attr1"][i]
			local buff = attacker.buffer[ind]
            local conf = BufferExcel.buffer[buff.id]
			local bufferCnt = delBuffer(attacker, ind)
			CombatImpl.addFrameBuffer(attacker, buff, CombatDefine.BUFFER_OP_DEL)
		end
	end
end

--持续治疗
function handler.hp(target, buffer,conf)
	if target.bufferCmd["noHp"] then
		return
	end
	if HANDLER_ONCE["hp"] == target.pos then
		return
	end
	local hp = buffer.arg
	
	local attacker = CombatImpl.objList[buffer.attackPos]
	if attacker and attacker.attr[RoleDefine.ZAOCHENG_HP_ADD_RATE] then
		local hpAddRate = attacker.attr[RoleDefine.ZAOCHENG_HP_ADD_RATE] / 10000
		hp = hp * (1 + hpAddRate)
	end
	local calcType = conf and conf.args[1] or 0
	if  CombatCalc.NO_EXCALC_LIST[calcType] and target.attr[RoleDefine.HP_ADD_RATE] then
		local hpAddRate = target.attr[RoleDefine.HP_ADD_RATE] / 10000
		hp = hp * (1 + hpAddRate)
	end
	hp = hp < 0 and 1 or hp
	if target.side == CombatDefine.DEFEND_SIDE then
		hp = CombatImpl.commonArgs.hpLimit or hp
	end
	local d = CombatObj.updateHp(target, hp, nil, nil, buffer.attackPos,CombatObj.BUFFER_HP_TYPE)
	buffer.attrs[RoleDefine.HP_COMBAT] = hp
	HANDLER_ONCE["hp"] = target.pos
end
--流血
function handler.liuxue(target, buffer,conf)
	local hurt = chixuHurtDel(target,buffer)
	local d = CombatObj.updateHp(target, -hurt, nil, nil, buffer.attackPos,CombatObj.BUFFER_HP_TYPE)
	buffer.attrs[RoleDefine.HP_COMBAT] = -hurt
	onExtraCombatRecord(buffer.attackPos,hurt,"liuxue")
end
--中毒
function handler.zhongdu(target, buffer,conf)
	local hurt = chixuHurtDel(target,buffer)
	local d = CombatObj.updateHp(target, -hurt, nil, nil, buffer.attackPos,CombatObj.BUFFER_HP_TYPE)
	buffer.attrs[RoleDefine.HP_COMBAT] = -hurt

	onExtraCombatRecord(buffer.attackPos,hurt,"zhongdu")
end
--燃烧
function handler.ranshao(target, buffer,conf)
	local hurt = chixuHurtDel(target,buffer)
	local d = CombatObj.updateHp(target, -hurt, nil, nil, buffer.attackPos,CombatObj.BUFFER_HP_TYPE)
	buffer.attrs[RoleDefine.HP_COMBAT] = -hurt

	onExtraCombatRecord(buffer.attackPos,hurt,"ranshao")
end
--燃烧
function handler.ranshao1(target, buffer,conf)
	local hurt = chixuHurtDel(target,buffer)
	local d = CombatObj.updateHp(target, -hurt, nil, nil, buffer.attackPos,CombatObj.BUFFER_HP_TYPE)
	buffer.attrs[RoleDefine.HP_COMBAT] = -hurt

	onExtraCombatRecord(buffer.attackPos,hurt,"ranshao")
end

--回合印记
function handler.huiheYinji(target, buffer,conf)
	if buffer.round > 1 then return end --最后一回合才生效
	local hurt = chixuHurtDel(target,buffer)
	local d = CombatObj.updateHp(target, -hurt, nil, nil, buffer.attackPos,CombatObj.BUFFER_HP_TYPE)
	buffer.attrs[RoleDefine.HP_COMBAT] = -hurt
end

--种子
function handler.zhongzi(target, buffer, conf)
	if buffer.round > 1 then return end --最后一回合才生效
	local cnt = #conf.args
	for i= 1, cnt do
        local bufferID = conf.args[i]	
		if canAdd(target,bufferID) then 
			addBuffer(buffer.attackPos, target, bufferID)
		end		
	end
end
--buffer包处理器
--偷取护甲
function handler.touquhujia(attacker,target,conf)
	local arg = conf.args[1]/10000
	local targetBufferID = conf.args[2]
	local attackerBufferID = conf.args[3]
	local def =  CombatObj.getValue(target,RoleDefine.DEF)
	--local rate = CombatObj.getValue(target,RoleDefine.DEF_RATE)/10000
	--def = def * (1 + rate)
	def = def > 0 and def or 0
	local arg = def * arg
	if arg > 0 then
		if canAdd(attacker,attackerBufferID) then 
			addBuffer(target.pos,attacker, attackerBufferID,nil,arg,conf)
		end
		
		if canAdd(target,targetBufferID) then 
			addBuffer(attacker.pos,target, targetBufferID,nil,-arg,conf)
		end
	end
end

--偷取攻击
function handler.touqugongji(attacker,target,conf)
	local arg = conf.args[1]/10000
	local targetBufferID = conf.args[2]
	local attackerBufferID = conf.args[3]
	local atk =  CombatObj.getValue(target,RoleDefine.ATK)
	--local rate = CombatObj.getValue(target,RoleDefine.ATK_RATE)/10000
	--def = def * (1 + rate)
	atk = atk > 0 and atk or 0
	local arg = atk * arg
	if arg > 0 then
		if canAdd(attacker,attackerBufferID) then 
			addBuffer(target.pos,attacker, attackerBufferID,nil,arg,conf)
		end
		
		if canAdd(target,targetBufferID) then 
			addBuffer(attacker.pos,target, targetBufferID,nil,-arg,conf)
		end
	end
end

function handler.totem(obj,buffer,conf)
	--图腾逻辑
	local buffers = conf.args
	for i = 1, #buffers do
		local bufferID = buffers[i][1]
		if type(bufferID) == "table" then
			local r = math.random(1,#bufferID)
			bufferID = bufferID[r]
		end
		local targetMode = buffers[i][2]
		local random = buffers[i][3]
		local targets = TargetMode.getTargets(obj, targetMode,{})
		if #targets > 0 then
			for _,target in ipairs(targets) do
				if canAdd(target,bufferID,random) then 
					addBuffer(obj.pos,target, bufferID)
				end
			end
		end
	end
end

function handler.groupbuffer(attacker,target,conf)
	for _,bufferID in ipairs(conf.args) do
		if canAdd(target,bufferID) then 
			addBuffer(attacker.pos,target, bufferID,nil,nil,conf)
		end	
	end
end

function handler.zuzhou(target,buffer,conf)
	local hurt = buffer.arg[1]
    local attacker = CombatImpl.objList[buffer.attackPos]

    -- 二次元结算方式调整成
    if BeSkill.getRandomBuffCmd(attacker, target, conf.cmd) and target.bufferCmd[conf.cmd] then
        hurt = hurt * #target.bufferCmd[conf.cmd]
    end

    local beSkillHurtRate = BeSkill.getBuffChixuHurt(attacker, conf.cmd)
    hurt = hurt * (1 + beSkillHurtRate)
	local d = CombatObj.updateHp(target, -hurt, nil, nil, buffer.attackPos,CombatObj.BUFFER_HP_TYPE)
	buffer.attrs[RoleDefine.HP_COMBAT] = -hurt

    BeSkill.handlerBuff(attacker, target, hurt, conf.cmd)
end

function yinbaoZuzhou(obj, skillTargets, skillConfig)
    local newFrame = nil
	for k,v in ipairs(skillTargets) do
		if v.bufferCmd["zuzhou"] then
			for i = #v.bufferCmd["zuzhou"],1,-1 do
                local ind = v.bufferCmd["zuzhou"][i]
				local buffer = v.buffer[ind]
                local conf = BufferExcel.buffer[buffer.id]
                if conf and handler[conf.cmd] then
                   handler[conf.cmd](v, buffer, conf)
                   CombatImpl.addFrameBuffer(v,buffer,CombatDefine.BUFFER_OP_HOLD)
                end

				local bufferCnt = delBuffer(v, ind)
				CombatImpl.addFrameBuffer(v,buffer,CombatDefine.BUFFER_OP_DEL)

                newFrame = true
			end
		end
	end
    -- 有引爆成功的
    if newFrame and ProjectLogic.isSsecy() then
       CombatImpl.addFrame()
    end
end

--主动技能释放后buff作用
handlerEx = {}
--印记
function handlerEx.yinJi(target, buffer, conf)
	local attacker = CombatImpl.objList[buffer.attackPos]
	if attacker == nil then
		return
	end
	
    local hurtRate = conf.args[1] 
	local hurtRateMax = conf.args[2]
	local hpMax = CombatObj.getHpMax(target) 
	local hurt =  hurtRate * hpMax  / 10000 
	local atk =  CombatObj.getValue(attacker,RoleDefine.ATK) * hurtRateMax / 10000
	if hurt > atk then
		hurt = atk
	end	
	local d = CombatObj.updateHp(target, -hurt, nil, nil, buffer.attackPos,CombatObj.BUFFER_HP_TYPE)
	buffer.attrs[RoleDefine.HP_COMBAT] = -hurt
	return true
end


function qingsuan(target)
	if target.hp <= 0 then
		return 0
	end
	local baseValue = 0
	local round
	for j = target.buffer[0], 1, -1 do
		local buffer = target.buffer[j]
		local conf = BufferExcel.buffer[buffer.id]
		local cmd = conf.cmd
		if cmd == "ranshao" or cmd == "ranshao1" or cmd == "liuxue" or cmd == "zhongdu" or cmd == "hurt" or cmd == "hurt1" then
			round = 1
			if buffer.round and buffer.round > 0 then
				round = buffer.round
			end 
			baseValue = baseValue + buffer.arg * round
			local bufferCnt = delBuffer(target, j)
			CombatImpl.addFrameBuffer(target,buffer,CombatDefine.BUFFER_OP_DEL)
		end
	end
	return baseValue
end

--解控
function jiekong(target)
	if target.hp <= 0 then
		return 0
	end
	local baseValue = 0
	local state = false
	for j = target.buffer[0], 1, -1 do
		local buffer = target.buffer[j]
		local conf = BufferExcel.buffer[buffer.id]
		local cmd = conf.cmd
		if isControlCmd(cmd) then
			local bufferCnt = delBuffer(target, j)
			CombatImpl.addFrameBuffer(target,buffer,CombatDefine.BUFFER_OP_DEL)
			state = true
		end
	end

	if state ==  true then
		CombatImpl.setExtraHit(target,nil, Skill.getCMD2ID("jiekong"))
	end
	
end
--杀意
function delShayi(target)
	if target.hp <= 0 then
		return 0
	end

	for j = target.buffer[0], 1, -1 do
		local buffer = target.buffer[j]
		local conf = BufferExcel.buffer[buffer.id]
		local cmd = conf.cmd
		if cmd == "shayi" then
			local bufferCnt = delBuffer(target, j)
			CombatImpl.addFrameBuffer(target,buffer,CombatDefine.BUFFER_OP_DEL)
		end
	end
end

function getBuffCnt(target,checkCmd)
	if target.hp <= 0 then
		return 0
	end
	local cnt = 0
	for j = target.buffer[0], 1, -1 do
		local buffer = target.buffer[j]
		local conf = BufferExcel.buffer[buffer.id]
		local cmd = conf.cmd
		if cmd == checkCmd then
			cnt = cnt + 1
		end
	end
	return cnt
end

-- 获取护盾值
function getBuffHuDun(obj)
	if obj and obj.bufferAttr and obj.bufferAttr[RoleDefine.HUDUN_COMBAT] then
		return obj.bufferAttr[RoleDefine.HUDUN_COMBAT]
	end
	return 0
end

-- 护盾值的修改
function updateHuDun(obj, value)
	if obj and obj.bufferAttr then
		local oldValue = obj.bufferAttr[RoleDefine.HUDUN_COMBAT] or 0 
		local newValue = oldValue + value
		if newValue <= 0 then
			obj.bufferAttr[RoleDefine.HUDUN_COMBAT] = 0
			delBufferByCmd(obj,"hudun", 0)
		else
			obj.bufferAttr[RoleDefine.HUDUN_COMBAT] = newValue
		end

		-- 护盾值没有全部去除  则 在对应英雄上吧 BUF 上的arg 数值 减除  防止 BufChange 重置 属性
		if value < 0 and newValue > 0 then
			if obj and obj.buffer then
				for j =  1 , obj.buffer[0] do       -- 从最早的护盾BUF中删除arg 
					local buffer = obj.buffer[j]
					local conf = BufferExcel.buffer[buffer.id]
					local bufferCmd = conf.cmd
					if bufferCmd == "hudun" then
						local have = buffer.arg
						if have > -value then
							buffer.arg = have + value
						else
							buffer.arg = 0
							local bufferCnt = delBuffer(obj, j)
							CombatImpl.addFrameBuffer(obj,buffer,CombatDefine.BUFFER_OP_DEL)
							break
						end
					end 
				end
			end
		end
	end	
end

BUFFER_COMBAT_TYPE = nil 

function initCombatBufferType()
	if BUFFER_COMBAT_TYPE then return end
	BUFFER_COMBAT_TYPE = {}
	for k,conf in pairs(BufferExcel.qusan) do
		if conf then
			BUFFER_COMBAT_TYPE[conf.buffcmd] = conf.type
		end
	end
end

--
function getCombatBufferCnt(target, qusanType)
    initCombatBufferType()
    local buffCnt = 0
	for i = target.buffer[0], 1, -1 do
		local buffer = target.buffer[i]
		local conf = BufferExcel.buffer[buffer.id]
		local cmd = conf.cmd
		if BUFFER_COMBAT_TYPE[cmd] and BUFFER_COMBAT_TYPE[cmd] == qusanType then
           buffCnt = buffCnt + 1
        end
    end
    return buffCnt
end

--抵抗
QUSAN_CMD2KEY = {
	["zuzhou"] = RoleDefine.STATUS_DIKANG_RATE9,
}

function qusan(target, qusanType,cnt)
	if target.isPet or not qusanType then
		return 0
	end

	initCombatBufferType()

	local state = false
	local delIndex = {}
	for i = target.buffer[0], 1, -1 do
		local buffer = target.buffer[i]
		local conf = BufferExcel.buffer[buffer.id]
		local cmd = conf.cmd
		if conf.noQusan ~= 1 then

			if BUFFER_COMBAT_TYPE[cmd] and BUFFER_COMBAT_TYPE[cmd] == qusanType then
				local isDiKang = nil
                local key = QUSAN_CMD2KEY[cmd]
	            local r = math.random(1,10000)
	            if key and target.attr[key] >= r then
	            	isDiKang = true
	            end
                if not isDiKang then
                   delIndex[#delIndex + 1] = i
                end
			elseif cmd == "attr" or cmd == "attrdne" then
				if conf.args and conf.args[1][2] < 0 and qusanType == 1 then
					delIndex[#delIndex + 1] = i
				elseif conf.args and conf.args[1][2] > 0 and qusanType == 2 then
					delIndex[#delIndex + 1] = i
				end
			end
		end
	end
	cnt = cnt or 0
	if cnt > 0 and cnt < #delIndex then
		for i = cnt + 1,#delIndex do
			delIndex[i] = nil
		end
	end
	for k,v in ipairs(delIndex) do
		local buffer = target.buffer[v]
		if not buffer then break end
		local bufferCnt = delBuffer(target, v)
		CombatImpl.addFrameBuffer(target,buffer,CombatDefine.BUFFER_OP_DEL)
	end

	return #delIndex
end

function qusanAddBuff(attacker, targets, bufferID)
    for _,target in ipairs(targets) do
	   if canAdd(target,bufferID) then 
	   	  addBuffer(attacker.pos, target, bufferID)
	   end
    end		
end

function beforeUpdateHp(obj,sum)
		local isStatus,cmd,ind = isStatus(obj,{"miansi","waitMiansi"})
		if not isStatus then
			return
		end
		--免死逻辑
		if cmd == "miansi" then
			return true
		end
		if sum == 0 and cmd == "waitMiansi" then
			local buffer = obj.buffer[ind]
			local bufferCnt = delBuffer(obj, ind)
			CombatImpl.addFrameBuffer(obj,buffer,CombatDefine.BUFFER_OP_DEL)
			local conf = BufferExcel.buffer[buffer.id]
			local bufferID = conf.args[1]
			if canAdd(obj,bufferID) then 
				addBuffer(obj.pos,obj, bufferID)
			end
			return true
		end
end

function checkBaohu(obj,value)

	local isStatus,cmd,ind = isStatus(obj,{"baohu"})
	if not isStatus then
		return value
	end
	local buffer = obj.buffer[ind]
	local attackPos = buffer.attackPos
	local attacker = CombatImpl.objList[attackPos]

	if attacker.hp <= 0 then
		return value
	end
	value = BeSkill.onCheckBuffer(attacker,obj,value)
	return value
end

function onExtraCombatRecord(pos,value,param)
	local obj = CombatObj.getObjByPos(pos)
	if not obj then return end

	obj.extraCombatRecord = obj.extraCombatRecord or {}
	if param == "zhongdu" then
		obj.extraCombatRecord.zhongdu = (obj.extraCombatRecord.zhongdu or 0) + value
	elseif param == "liuxue" then
		obj.extraCombatRecord.liuxue = (obj.extraCombatRecord.liuxue or 0) + value
	elseif param == "ranshao" then
		obj.extraCombatRecord.ranshao = (obj.extraCombatRecord.ranshao or 0) + value
	elseif param == "xuanyun" then
		obj.extraCombatRecord.xuanyun = (obj.extraCombatRecord.xuanyun or 0) + value
	elseif param == "revive" then
		obj.extraCombatRecord.revive = (obj.extraCombatRecord.revive or 0) + value
	elseif param == "reviveBeUse" then
		obj.extraCombatRecord.reviveBeUse = (obj.extraCombatRecord.reviveBeUse or 0) + value
	elseif param == "kill" then
		obj.extraCombatRecord.kill = (obj.extraCombatRecord.kill or 0) + value
	end
end